<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Security Tips and Tricks</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/security-customization" />
  <meta property="og:title" content="Quarkus - Security Tips and Tricks" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/security-customization">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Security Tips and Tricks</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#httpauthenticationmechanism-customization">HttpAuthenticationMechanism Customization</a></li>
<li><a href="#security-identity-customization">Security Identity Customization</a></li>
<li><a href="#custom-jax-rs-securitycontext">Custom JAX-RS SecurityContext</a></li>
<li><a href="#disabling-authorization">Disabling Authorization</a></li>
<li><a href="#registering-security-providers">Registering Security Providers</a></li>
<li><a href="#reactive-security">Reactive Security</a></li>
</ul></div>
    <div>
      <div class="sect1">
<h2 id="httpauthenticationmechanism-customization"><a class="anchor" href="#httpauthenticationmechanism-customization"></a>HttpAuthenticationMechanism Customization</h2>
<div class="sectionbody">
<div class="paragraph">
<p>One can customize <code>HttpAuthenticationMechanism</code> by registering a CDI implementation bean.
In the example below the custom authenticator delegates to <code>JWTAuthMechanism</code> provided by <code>quarkus-smallrye-jwt</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Alternative
@Priority(1)
@ApplicationScoped
public class CustomAwareJWTAuthMechanism implements HttpAuthenticationMechanism {

	private static final Logger LOG = LoggerFactory.getLogger(CustomAwareJWTAuthMechanism.class);

	@Inject
	JWTAuthMechanism delegate;

	@Override
	public Uni&lt;SecurityIdentity&gt; authenticate(RoutingContext context, IdentityProviderManager identityProviderManager) {
	    // do some custom action and delegate
            return delegate.authenticate(context, identityProviderManager);
	}

	@Override
	public Uni&lt;ChallengeData&gt; getChallenge(RoutingContext context) {
		return delegate.getChallenge(context);
	}

	@Override
	public Set&lt;Class&lt;? extends AuthenticationRequest&gt;&gt; getCredentialTypes() {
		return delegate.getCredentialTypes();
	}

	@Override
	public HttpCredentialTransport getCredentialTransport() {
		return delegate.getCredentialTransport();
	}

}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="security-identity-customization"><a class="anchor" href="#security-identity-customization"></a>Security Identity Customization</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Internally, the identity providers create and update an instance of the <code>io.quarkus.security.identity.SecurityIdentity</code> class which holds the principal, roles, credentials which were used to authenticate the client (user) and other security attributes. An easy option to customize <code>SecurityIdentity</code> is to register a custom <code>SecurityIdentityAugmentor</code>. For example, the augmentor below adds an addition role:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import io.quarkus.security.identity.AuthenticationRequestContext;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.SecurityIdentityAugmentor;
import io.quarkus.security.runtime.QuarkusSecurityIdentity;
import io.smallrye.mutiny.Uni;

import javax.enterprise.context.ApplicationScoped;
import java.util.function.Supplier;

@ApplicationScoped
public class RolesAugmentor implements SecurityIdentityAugmentor {

    @Override
    public int priority() {
        return 0;
    }

    @Override
    public Uni&lt;SecurityIdentity&gt; augment(SecurityIdentity identity, AuthenticationRequestContext context) {
        return context.runBlocking(build(identity));
    }

    private Supplier&lt;SecurityIdentity&gt; build(SecurityIdentity identity) {
        if(identity.isAnonymous()) {
            return () -&gt; identity;
        } else {
            // create a new builder and copy principal, attributes, credentials and roles from the original
            QuarkusSecurityIdentity.Builder builder = QuarkusSecurityIdentity.builder()
                    .setPrincipal(identity.getPrincipal())
                    .addAttributes(identity.getAttributes())
                    .addCredentials(identity.getCredentials())
                    .addRoles(identity.getRoles());

            // add custom role source here
            builder.addRole("dummy");
            return builder::build;
        }
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="custom-jax-rs-securitycontext"><a class="anchor" href="#custom-jax-rs-securitycontext"></a>Custom JAX-RS SecurityContext</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you use JAX-RS <code>ContainerRequestFilter</code> to set a custom JAX-RS <code>SecurityContext</code> then make sure <code>ContainerRequestFilter</code> runs in the JAX-RS pre-match phase by adding a <code>@PreMatching</code> annotation to it for this custom security context to be linked with Quarkus <code>SecurityIdentity</code>, for example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import java.security.Principal;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.ext.Provider;

@Provider
@PreMatching
public class SecurityOverrideFilter implements ContainerRequestFilter {
    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        String user = requestContext.getHeaders().getFirst("User");
        String role = requestContext.getHeaders().getFirst("Role");
        if (user != null &amp;&amp; role != null) {
            requestContext.setSecurityContext(new SecurityContext() {
                @Override
                public Principal getUserPrincipal() {
                    return new Principal() {
                        @Override
                        public String getName() {
                            return user;
                        }
                    };
                }

                @Override
                public boolean isUserInRole(String r) {
                    return role.equals(r);
                }

                @Override
                public boolean isSecure() {
                    return false;
                }

                @Override
                public String getAuthenticationScheme() {
                    return "basic";
                }
            });
        }

    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="disabling-authorization"><a class="anchor" href="#disabling-authorization"></a>Disabling Authorization</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you have a good reason to disable the authorization (for example, when testing) then you can register a custom <code>AuthorizationController</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Alternative
@Priority(Interceptor.Priority.LIBRARY_AFTER)
@ApplicationScoped
public class DisabledAuthController extends AuthorizationController {
    @ConfigProperty(name = "disable.authorization")
    boolean disableAuthorization;

    @Override
    public boolean isAuthorizationEnabled() {
        return disableAuthorization;
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="registering-security-providers"><a class="anchor" href="#registering-security-providers"></a>Registering Security Providers</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When running in native mode, the default behavior for GraalVM native executable generation is to only include the main "SUN" provider
unless you have enabled SSL, in which case all security providers are registered. If you are not using SSL, then you can selectively
register security providers by name using the <code>quarkus.security.security-providers</code> property. The following example illustrates
configuration to register the "SunRsaSign" and "SunJCE" security providers:</p>
</div>
<div class="listingblock">
<div class="title">Example Security Providers Configuration</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs">quarkus.security.security-providers=SunRsaSign,SunJCE</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="reactive-security"><a class="anchor" href="#reactive-security"></a>Reactive Security</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you are going to use security in a reactive environment, you will likely need SmallRye Context Propagation:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
  &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
  &lt;artifactId&gt;quarkus-smallrye-context-propagation&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This will allow you to propagate the identity throughout the reactive callbacks. You also need to make sure you
are using an executor that is capable of propagating the identity (e.g. no <code>CompletableFuture.supplyAsync</code>),
to make sure that quarkus can propagate it. For more information see the
<a href="context-propagation">Context Propagation Guide</a>.</p>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
